package com.codeyang.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codeyang.domain.UserAddr;
import com.codeyang.mapper.UserAddrMapper;
import com.codeyang.service.UserAddrService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;

/**
 * 描述: TO-删除标志-DO
 *
 * @author CodeYang_Site
 * @version 2021/5/27 12:23
 */
@Slf4j
@CacheConfig(cacheNames = "com.codeyang.service.impl.UserAddrServiceImpl")
@Service
public class UserAddrServiceImpl extends ServiceImpl<UserAddrMapper, UserAddr> implements UserAddrService {


    @Autowired
    private UserAddrMapper userAddrMapper;

    /**
     * 根据用户id 加载用户收藏地址,缓存一下.在配置文件中设置了所有的缓存默认缓存3600秒
     *
     * @param userId
     * @return
     */
    @Cacheable(key = "#userId")
    @Override
    public List<UserAddr> findUserAddr(String userId) {
        List<UserAddr> userAddrs = userAddrMapper.selectList(
                new LambdaQueryWrapper<UserAddr>()
                        .eq(UserAddr::getUserId, userId)
                        //查询没有被删除的address
                        .eq(UserAddr::getStatus, 1)
                        // 多字段培训 comm 默认地址  create时间
                        .orderByDesc(UserAddr::getCommonAddr, UserAddr::getCreateTime)
                //也可以使用 .last(sql) 最后拼接SQL上去
        );
        return userAddrs;
    }

    /**
     * 添加用户收货地址
     * involve cache update mast delete|put cache
     * "#userAddr.userId" 这样拿到时用户登录的id 可以删除指定用户的数据
     * 1.如果 用户从来没有收货地址  新增的地址就是默认的
     *
     * @param
     * @return
     */
    @CacheEvict(key = "#userAddr.userId")
    @Override
    public boolean save(UserAddr userAddr) {
        log.info("新增用户收货地址");
        userAddr.setUpdateTime(new Date());
        userAddr.setCreateTime(new Date());
        userAddr.setVersion(1);
        userAddr.setStatus(1);
        //1.查看用户存储的地址是不是之前的地址
        Integer count = userAddrMapper.selectCount(new LambdaQueryWrapper<UserAddr>()
                .eq(UserAddr::getUserId, userAddr.getUserId())
                .eq(UserAddr::getStatus, 1)
        );
        //判null一下
        // 如果之前没有收货地址,那么这个就是默认地址
        if (null == count || count.equals(0)) {
            userAddr.setCommonAddr(1);
        }
        //insert DB
        return userAddrMapper.insert(userAddr) > 0;
    }

    /**
     * 修改用户默认收货地址:
     * step:
     * 1.判断地址传入是否存在,防止非法 操作
     * 2.判断传入地址是不是之前的默认收货地址
     * 3.新增收货地址
     *
     * @param userId
     * @param addrId
     */
    @CacheEvict(key = "#userId")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void changeUserAddr(String userId, Long addrId) {
        //1.
        log.info("修改用户的默认收货地址，用户为：{},新地址id为：{}", userId, addrId);
        UserAddr oldUserAddr = userAddrMapper.selectOne(new LambdaQueryWrapper<UserAddr>()
                .eq(UserAddr::getUserId, userId)
                .eq(UserAddr::getCommonAddr, 1)
        );
        if (oldUserAddr.getAddrId().equals(addrId)) {
            //是原来的地址不改
            return;
        }
        //3.要改 先把老的地址改为不是默认地址 在将新的地址设为默认地址
        oldUserAddr.setCommonAddr(0);
        oldUserAddr.setUpdateTime(new Date());

        int i = userAddrMapper.updateById(oldUserAddr);
        if (i > 0) {
            // 处理新的地址
            UserAddr newUserAddr = userAddrMapper.selectById(addrId);
            //这里我们应该把错误收集起来, 处理一下,不让前端直接看错误信息
            if (ObjectUtils.isEmpty(newUserAddr)) {
                throw new IllegalArgumentException("新的默认地址在DB中不存在");
            }
            newUserAddr.setCommonAddr(1);
            newUserAddr.setUpdateTime(new Date());
            userAddrMapper.updateById(newUserAddr);
        }

    }
}
